<?
define('CRLF', "\r\n", TRUE);
class Mail_mimePart{

	var $_encoding;
	var $_subparts;
	var $_encoded;
    var $_headers;
    var $_body;
	
	/***********************************************/
    function Mail_mimePart($body, $params = array())
    {
        if (!defined('MAIL_MIMEPART_CRLF')) {
            define('MAIL_MIMEPART_CRLF', "\r\n", TRUE);
        }

        foreach ($params as $key => $value) {
            switch ($key) {
                case 'content_type':
                    $headers['Content-Type'] = $value . (isset($charset) ? '; charset="' . $charset . '"' : '');
                    break;

                case 'encoding':
                    $this->_encoding = $value;
                    $headers['Content-Transfer-Encoding'] = $value;
                    break;

                case 'cid':
                    $headers['Content-ID'] = '<' . $value . '>';
                    break;

                case 'disposition':
                    $headers['Content-Disposition'] = $value . (isset($dfilename) ? '; filename="' . $dfilename . '"' : '');
                    break;

                case 'dfilename':
                    if (isset($headers['Content-Disposition'])) {
                        $headers['Content-Disposition'] .= '; filename="' . $value . '"';
                    } else {
                        $dfilename = $value;
                    }
                    break;

                case 'description':
                    $headers['Content-Description'] = $value;
                    break;

                case 'charset':
                    if (isset($headers['Content-Type'])) {
                        $headers['Content-Type'] .= '; charset="' . $value . '"';
                    } else {
                        $charset = $value;
                    }
                    break;
            }
        }

        if (!isset($_headers['Content-Type'])) {
            $_headers['Content-Type'] = 'text/plain';
        }

        $this->_encoded  =  array();
        $this->_headers  =& $headers;
        $this->_body     =  $body;
    }
	/***********************************************/
    function encode()
    {
        $encoded =& $this->_encoded;

        if (!empty($this->_subparts)) {
            srand((double)microtime()*1000000);
            $boundary = '=_' . md5(uniqid(rand()) . microtime());
            $this->_headers['Content-Type'] .= ';' . MAIL_MIMEPART_CRLF . chr(9) . 'boundary="' . $boundary . '"';

            for ($i = 0; $i < count($this->_subparts); $i++) {
                $headers = array();
                $tmp = $this->_subparts[$i]->encode();
                foreach ($tmp['headers'] as $key => $value) {
                    $headers[] = $key . ': ' . $value;
                }
                $subparts[] = implode(MAIL_MIMEPART_CRLF, $headers) . MAIL_MIMEPART_CRLF . MAIL_MIMEPART_CRLF . $tmp['body'];
            }

            $encoded['body'] = '--' . $boundary . MAIL_MIMEPART_CRLF .
                               implode('--' . $boundary . MAIL_MIMEPART_CRLF, $subparts) .
                               '--' . $boundary.'--' . MAIL_MIMEPART_CRLF;

        } else {
            $encoded['body'] = $this->_getEncodedData($this->_body, $this->_encoding) . MAIL_MIMEPART_CRLF;
        }

        $encoded['headers'] =& $this->_headers;

        return $encoded;
    }
	/***********************************************/
    function &addSubPart($body, $params)
    {
        $this->_subparts[] = new Mail_mimePart($body, $params);
        return $this->_subparts[count($this->_subparts) - 1];
    }
	/***********************************************/
    function _getEncodedData($data, $encoding)
    {
        switch ($encoding) {
            case '7bit':
                return $data;
                break;

            case 'quoted-printable':
                return $this->_quotedPrintableEncode($data);
                break;

            case 'base64':
                return rtrim(chunk_split(base64_encode($data), 76, MAIL_MIMEPART_CRLF));
                break;
        }
    }
	
	/***********************************************/
    function _quotedPrintableEncode($input , $line_max = 76)
    {
        $lines    = preg_split("/\r\n|\r|\n/", $input);
        $eol    = MAIL_MIMEPART_CRLF;
        $escape    = '=';
        $output    = '';
        
        while(list(, $line) = each($lines)){

            $linlen     = strlen($line);
            $newline = '';

            for ($i = 0; $i < $linlen; $i++) {
                $char = substr($line, $i, 1);
                $dec  = ord($char);

                if (($dec == 32) AND ($i == ($linlen - 1))){
                    $char = '=20';

                } elseif($dec == 9) {
                    ;
                } elseif(($dec == 61) OR ($dec < 32 ) OR ($dec > 126)) {
                    $char = $escape . strtoupper(sprintf('%02s', dechex($dec)));
                }
    
                if ((strlen($newline) + strlen($char)) >= $line_max) {
                    $output  .= $newline . $escape . $eol;
                    $newline  = '';
                }
                $newline .= $char;
            }
            $output .= $newline . $eol;
        }
        $output = substr($output, 0, -1 * strlen($eol));
        return $output;
    }
}# End of the class
	/***********************************************/
	/***********************************************/
	/***********************************************/		


class html_mail{

	var $html;
	var $text;
	var $output;
	var $html_text;
	var $html_images;
	var $image_types;
	var $build_params;
	var $attachments;
	var $headers;

	/***********************************************/
	function html_mail($headers = array()){

		if(!defined('CRLF'))
			define('CRLF', "\n", TRUE);

		$this->html_images	= array();
		$this->headers		= array();

		$this->image_types = array(
									'gif'	=> 'image/gif',
									'jpg'	=> 'image/jpeg',
									'jpeg'	=> 'image/jpeg',
									'jpe'	=> 'image/jpeg',
									'bmp'	=> 'image/bmp',
									'png'	=> 'image/png',
									'tif'	=> 'image/tiff',
									'tiff'	=> 'image/tiff',
									'swf'	=> 'application/x-shockwave-flash'
								  );

		$this->build_params['html_encoding']	= 'quoted-printable';
		$this->build_params['text_encoding']	= '7bit';
		$this->build_params['html_charset']		= 'iso-8859-1';
		$this->build_params['text_charset']		= 'iso-8859-1';
		$this->build_params['text_wrap']		= 998;

		$this->headers[] = 'MIME-Version: 1.0';

		foreach($headers as $value){
			if(!empty($value))
				$this->headers[] = $value;
		}
	}

	/***********************************************/
	function get_file($filename){

		$return = '';
		if($fp = fopen($filename, 'rb')){
			while(!feof($fp)){
				$return .= fread($fp, 1024);
			}
			fclose($fp);
			return $return;

		}else{
			return FALSE;
		}
	}

	/***********************************************/
	function find_html_images($images_dir) {

		while(list($key,) = each($this->image_types))
			$extensions[] = $key;

		preg_match_all('/"([^"]+\.('.implode('|', $extensions).'))"/Ui', $this->html, $images);

		for($i=0; $i<count($images[1]); $i++){
			if(file_exists($images_dir.$images[1][$i])){
				$html_images[] = $images[1][$i];
				$this->html = str_replace($images[1][$i], basename($images[1][$i]), $this->html);
			}
		}

		if(!empty($html_images)){

			$html_images = array_unique($html_images);
			sort($html_images);
	
			for($i=0; $i<count($html_images); $i++){
				if($image = $this->get_file($images_dir.$html_images[$i])){
					$content_type = $this->image_types[substr($html_images[$i], strrpos($html_images[$i], '.') + 1)];
					$this->add_html_image($image, basename($html_images[$i]), $content_type);
				}
			}
		}
	}

	/***********************************************/
	function add_text($text = ''){
		$this->text = $text;
	}

	/***********************************************/
	function add_html($html, $text = NULL, $images_dir = NULL){

		$this->html			= $html;
		$this->html_text	= $text;

		if(isset($images_dir))
			$this->find_html_images($images_dir);
	}

	/***********************************************/
	function add_html_image($file, $name = '', $c_type='application/octet-stream'){
		$this->html_images[] = array(
										'body'   => $file,
										'name'   => $name,
										'c_type' => $c_type,
										'cid'    => md5(uniqid(time()))
									);
	}


	/***********************************************/
	function add_attachment($file, $name = '', $c_type='application/octet-stream', $encoding = 'base64'){
		$this->attachments[] = array(
									'body'		=> $file,
									'name'		=> $name,
									'c_type'	=> $c_type,
									'encoding'	=> $encoding
								  );
	}

	/***********************************************/
	function &add_text_part(&$obj, $text){

		$params['content_type'] = 'text/plain';
		$params['encoding']     = $this->build_params['text_encoding'];
		$params['charset']      = $this->build_params['text_charset'];
		if(is_object($obj)){
			return $obj->addSubpart($text, $params);
		}else{
			return new Mail_mimePart($text, $params);
		}
	}

	/***********************************************/
	function &add_html_part(&$obj){

		$params['content_type'] = 'text/html';
		$params['encoding']     = $this->build_params['html_encoding'];
		$params['charset']      = $this->build_params['html_charset'];
		if(is_object($obj)){
			return $obj->addSubpart($this->html, $params);
		}else{
			return new Mail_mimePart($this->html, $params);
		}
	}

	/***********************************************/
	function &add_mixed_part(){

		$params['content_type'] = 'multipart/mixed';
		return new Mail_mimePart('', $params);
	}

	/***********************************************/
	function &add_alternative_part(&$obj){

		$params['content_type'] = 'multipart/alternative';
		if(is_object($obj)){
			return $obj->addSubpart('', $params);
		}else{
			return new Mail_mimePart('', $params);
		}
	}

	/***********************************************/
	function &add_related_part(&$obj){

		$params['content_type'] = 'multipart/related';
		if(is_object($obj)){
			return $obj->addSubpart('', $params);
		}else{
			return new Mail_mimePart('', $params);
		}
	}

	/***********************************************/
	function &add_html_image_part(&$obj, $value){

		$params['content_type'] = $value['c_type'];
		$params['encoding']     = 'base64';
		$params['disposition']  = 'inline';
		$params['dfilename']    = $value['name'];
		$params['cid']          = $value['cid'];
		$obj->addSubpart($value['body'], $params);
	}

	/***********************************************/
	function &add_attachment_part(&$obj, $value){

		$params['content_type'] = $value['c_type'];
		$params['encoding']     = $value['encoding'];
		$params['disposition']  = 'attachment';
		$params['dfilename']    = $value['name'];
		$obj->addSubpart($value['body'], $params);
	}

	/***********************************************/
	function build_message($params = array()){

		if(count($params) > 0)
			while(list($key, $value) = each($params))
				$this->build_params[$key] = $value;

		if(!empty($this->html_images))
			foreach($this->html_images as $value)
				$this->html = str_replace($value['name'], 'cid:'.$value['cid'], $this->html);

		$null        = NULL;
		$attachments = !empty($this->attachments) ? TRUE : FALSE;
		$html_images = !empty($this->html_images) ? TRUE : FALSE;
		$html        = !empty($this->html)        ? TRUE : FALSE;
		$text        = isset($this->text)         ? TRUE : FALSE;

		switch(TRUE){
			case $text AND !$attachments:
				$message =& $this->add_text_part($null, $this->text);
				break;

			case !$text AND $attachments AND !$html:
				$message =& $this->add_mixed_part();

				for($i=0; $i<count($this->attachments); $i++)
					$this->add_attachment_part($message, $this->attachments[$i]);
				break;

			case $text AND $attachments:
				$message =& $this->add_mixed_part();
				$this->add_text_part($message, $this->text);

				for($i=0; $i<count($this->attachments); $i++)
					$this->add_attachment_part($message, $this->attachments[$i]);
				break;

			case $html AND !$attachments AND !$html_images:
				if(!is_null($this->html_text)){
					$message =& $this->add_alternative_part($null);
					$this->add_text_part($message, $this->html_text);
					$this->add_html_part($message);
				}else{
					$message =& $this->add_html_part($null);
				}
				break;

			case $html AND !$attachments AND $html_images:
				if(!is_null($this->html_text)){
					$message =& $this->add_alternative_part($null);
					$this->add_text_part($message, $this->html_text);
					$related =& $this->add_related_part($message);
				}else{
					$message =& $this->add_related_part($null);
					$related =& $message;
				}
				$this->add_html_part($related);
				for($i=0; $i<count($this->html_images); $i++)
					$this->add_html_image_part($related, $this->html_images[$i]);
				break;

			case $html AND $attachments AND !$html_images:
				$message =& $this->add_mixed_part();
				if(!is_null($this->html_text)){
					$alt =& $this->add_alternative_part($message);
					$this->add_text_part($alt, $this->html_text);
					$this->add_html_part($alt);
				}else{
					$this->add_html_part($message);
				}
				for($i=0; $i<count($this->attachments); $i++)
					$this->add_attachment_part($message, $this->attachments[$i]);
				break;

			case $html AND $attachments AND $html_images:
				$message =& $this->add_mixed_part();
				if(!is_null($this->html_text)){
					$alt =& $this->add_alternative_part($message);
					$this->add_text_part($alt, $this->html_text);
					$rel =& $this->add_related_part($alt);
				}else{
					$rel =& $this->add_related_part($message);
				}
				$this->add_html_part($rel);
				for($i=0; $i<count($this->html_images); $i++)
					$this->add_html_image_part($rel, $this->html_images[$i]);
				for($i=0; $i<count($this->attachments); $i++)
					$this->add_attachment_part($message, $this->attachments[$i]);
				break;

		}

		if(isset($message)){
			$output = $message->encode();
			$this->output = $output['body'];

			foreach($output['headers'] as $key => $value){
				$headers[] = $key.': '.$value;
			}

			$this->headers = array_merge($this->headers, $headers);
			return TRUE;
		}else
			return FALSE;
	}

	/***********************************************/
	function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '',$enable_html = true){

		$to		= ($to_name != '')   ? '"'.$to_name.'" <'.$to_addr.'>' : $to_addr;
		$from	= ($from_name != '') ? '"'.$from_name.'" <'.$from_addr.'>' : $from_addr;
		if(is_string($headers))
			$headers = explode(CRLF, trim($headers));

		for($i=0; $i<count($headers); $i++){
			if(is_array($headers[$i]))
				for($j=0; $j<count($headers[$i]); $j++)
					if($headers[$i][$j] != '')
						$xtra_headers[] = $headers[$i][$j];

			if($headers[$i] != '')
				$xtra_headers[] = $headers[$i];
		}
		if(!isset($xtra_headers))
			$xtra_headers = array();
		echo("<br>Header:====" . $xtra_headers[0]);
		echo("<br><br>".'From: '.$from.CRLF.implode(CRLF, $this->headers).CRLF.implode(CRLF, $xtra_headers));
		
		return mail($to, $subject, $this->output, 'From: '.$from.CRLF.implode(CRLF, $this->headers).CRLF.implode(CRLF, $xtra_headers));
		
	}

	/***********************************************/
	function smtp_send(&$smtp, $params = array()){
		foreach($params as $key => $value){
			switch($key){
				case 'headers':
					$headers = $value;
					break;

				case 'from':
					$send_params['from'] = $value;
					break;

				case 'recipients':
					$send_params['recipients'] = $value;
					break;
			}
		}

		$send_params['body']	= $this->output;
		$send_params['headers']	= array_merge($this->headers, $headers);

		return $smtp->send($send_params);
	}

	/***********************************************/
	function get_rfc822($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = ''){

		$date = 'Date: '.date('D, d M y H:i:s');
		$to   = ($to_name   != '') ? 'To: "'.$to_name.'" <'.$to_addr.'>' : 'To: '.$to_addr;
		$from = ($from_name != '') ? 'From: "'.$from_name.'" <'.$from_addr.'>' : 'From: '.$from_addr;

		if(is_string($subject))
			$subject = 'Subject: '.$subject;

		if(is_string($headers))
			$headers = explode(CRLF, trim($headers));

		for($i=0; $i<count($headers); $i++){
			if(is_array($headers[$i]))
				for($j=0; $j<count($headers[$i]); $j++)
					if($headers[$i][$j] != '')
						$xtra_headers[] = $headers[$i][$j];

			if($headers[$i] != '')
				$xtra_headers[] = $headers[$i];
		}

		if(!isset($xtra_headers))
			$xtra_headers = array();

		$headers = array_merge($this->headers, $xtra_headers);

		return $date.CRLF.$from.CRLF.$to.CRLF.$subject.CRLF.implode(CRLF, $headers).CRLF.CRLF.$this->output;
	
	}


}# End of class.
	/***********************************************/
	/***********************************************/
	/***********************************************/
	
	
class email{

	var $fromname = "";
	var $toname = "";
	var $from = "";
	var $to = "";
	var $cc = "";
	var $bcc = "";
	var $subject = "";
	var $body = "";
	var $headers = "";
	
	var $enable_html = true;
	
	var $attachment = "";
	var $themail;
	
	/***********************************************/
	function email(){
		$this->from = "";
		$this->to = "";
		$this->cc = "";
		$this->bcc = "";
		$this->subject = "";
		$this->body = "";
		$this->headers = "";
		$this->themail = new html_mail(array('X-Mailer: Html Mime Mail Class'));
	}

	/***********************************************/
	function attachment($filename, $encode="text/html"){
		
		$this->attachment = $this->themail->get_file($filename);
        $this->themail->add_attachment($this->attachment, $filename);
	}

	/***********************************************/
	
	function send(){
		
		$this->headers .= "MIME-Version: 1.0 \n"; 
		if($this->enable_html == true){
		    $this->headers .= "Content-type: text/html; charset=utf-8\n";
		}
    	$this->headers .= "From:" . $this->from . "\r\nCc:" . $this->cc . "\r\nBcc:" . $this->bcc;
		
		if($this->attachment != ""){
			if($this->send_with_attachment()==true){
				return true;
			} else {
				return false;
			}
		}
		
		if (@mail ($this->to, $this->subject, $this->body, $this->headers)){ 
			return true;
		} else {
			return false;
		}
	}
	
	/***********************************************/
	function send_with_attachment(){
		
		$this->themail->add_text($this->body);
		$this->themail->build_message();
		if($this->themail->send($this->toname, $this->to, $this->fromname, $this->from, $this->subject, $this->headers, $this->enable_html)){
			return true;
		} else {
			return true;
		}
	}
	
	/***********************************************/
	function is_valid($email)
	{
		return preg_match('#^[a-z0-9.!\#$%&\'*+-/=?^_`{|}~]+@([0-9.]+|([a-z0-9._-]+\.+[a-z]{2,4}))$#si', $email);
	}
	
	/***********************************************/
}
?>